﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Bricks.Business.Service.Impl;
using Bricks.Site.Models;
using Bricks.Business.Models.FlowProcess;
using System.Xml;
using System.Web.Script.Serialization;
using Bricks.Business.Service;
using Bricks.Component.Utils;
using Bricks.Site.Web.CommonUtils;
using System.Collections;
using Bricks.Business.Models.Account;
using System.Text;
using Bricks.Component.Utils.Extensions;
using System.Configuration;
using Bricks.Component.Data;
using Bricks.Site.Models.DBViewModel.Contract;
using Bricks.Business.Service.CommonSupport;

namespace Bricks.Site.Web.Controllers
{
    [Export]
    public class AlterOrderController : BaseController
    {
        #region 属性
        [Import]
        public IFlowNodeService FlowNodeService { get; set; }
        [Import]
        public IAlterOrderService AlterOrderService { get; set; }
        [Import]
        public IBaklogTaskService BaklogTaskService { get; set; }
        [Import]
        public IFlowUtilsService FlowUtilsService { get; set; }
        [Import]
        public IUserOrgService UserOrgService { get; set; }
        [Import]
        public IOrgInfoService OrgInfoService { get; set; }
        #endregion

        /// <summary>
        /// 流程管理界面初始化
        /// </summary>
        /// <param name="sourceType">来源类型</param>
        /// <param name="processType">处理类型</param>
        /// <param name="sourceID">关联的记录ID</param>
        /// <param name="associatedNodeCode">关联的流程节点编码</param>
        /// <param name="lastUpdateUserDepartment">最后修改人部门</param>
        /// <param name="lastUpdateUser">最后修改人</param>
        /// <param name="alterOrderID">单据ID</param>
        /// <returns></returns>
        public ActionResult AlterOrder(string sourceType, string processType, string sourceID, string associatedNodeCode, string lastUpdateUserDepartment, string lastUpdateUser, string alterOrderID)
        {
            AlterOrderView alterOrderView = null;
            string processdOrCirculatedNodeCode = string.Empty;
            string processdOrCirculatedUserDepartment = string.Empty;
            if (sourceType == "1") //新增变更令申请
            {
                string flowCode = GetFlowCode(lastUpdateUserDepartment);
                alterOrderView = new AlterOrderView();
                alterOrderView.ID = Guid.NewGuid();
                alterOrderView.AlterOrderID = Guid.NewGuid();
                alterOrderView.FlowCode = flowCode;
                alterOrderView.AlterType = "一般";
                alterOrderView.AlterMoney = 0;
                alterOrderView.AlterDate = 0;
                alterOrderView.RequestPerson = User.Identity.Name;
                alterOrderView.RequestDate = DateTime.Now;
                alterOrderView.HandleState = "0";
                alterOrderView.AssociatedNodeCode = FlowNodeService.GetFlowNodeByNodeCode(flowCode, true, "").NodeCode;
                alterOrderView.LastUpdateUserDepartment = lastUpdateUserDepartment;
                alterOrderView.LastUpdateUser = User.Identity.Name;
                processdOrCirculatedNodeCode = alterOrderView.AssociatedNodeCode;
                processdOrCirculatedUserDepartment = lastUpdateUserDepartment;
            }
            else if (sourceType == "2" && processType == "1") //待办
            {
                alterOrderView = AlterOrderService.GetAlterOrderBackupByCondition(alterOrderID, associatedNodeCode, lastUpdateUserDepartment, lastUpdateUser);
            }
            else
            {
                alterOrderView = AlterOrderService.GetAlterOrderByID(alterOrderID);
            }

            if (sourceType == "2" || (sourceType == "3" && (processType == "1" || processType == "4" || processType == "5")))
            {
                processdOrCirculatedNodeCode = associatedNodeCode;
                processdOrCirculatedUserDepartment = lastUpdateUserDepartment;
            }
            alterOrderView.AlterOrderBillListJson = "";
            alterOrderView.SourceType = sourceType;
            alterOrderView.ProcessType = processType;
            alterOrderView.SourceID = sourceID;
            alterOrderView.ProcessdOrCirculatedNodeCode = processdOrCirculatedNodeCode;
            alterOrderView.ProcessdOrCirculatedUserDepartment = processdOrCirculatedUserDepartment;
            ViewBag.RefAlterCodeInfo = alterOrderView.RefAlterCode;
            ConstructTools(alterOrderView);
            return View(alterOrderView);
        }

        public string GetFlowCode(string userDepartment)
        {
            return "AlterOrderOne";
        }

        /// <summary>
        /// 获取清单数据
        /// </summary>
        /// <param name="sourceType">来源类型</param>
        /// <param name="associatedNodeCode">关联的流程节点编码</param>
        /// <param name="lastUpdateUserDepartment">最后修改人部门</param>
        /// <param name="lastUpdateUser">最后修改人</param>
        /// <param name="alterID">单据ID</param>
        /// <returns></returns>
        public ActionResult AlterOrderBillList(string sourceType, string processType, string associatedNodeCode, string lastUpdateUserDepartment, string lastUpdateUser, string alterOrderID)
        {
            if ((sourceType == "0" && processType == "2") || (sourceType == "2" && processType == "1"))
            {
                return Json(AlterOrderService.GetAlterOrderBillBackupList(Guid.Parse(alterOrderID), associatedNodeCode, lastUpdateUserDepartment, lastUpdateUser));
            }
            else
            {
                return Json(AlterOrderService.GetAlterOrderBillList(Guid.Parse(alterOrderID)));
            }
        }

        #region 根据功能权限和业务权限构造工具栏菜单按钮
        private void ConstructTools(AlterOrderView alterOrderView)
        {
            List<UIFunctionView> menuActions = base.GetUserMenuActions();
            StringBuilder sb = new StringBuilder();

            //过程管理列表单据双击或单击超链接，只能查看
            if (alterOrderView.SourceType == "0")
            {
                SetAllDisabled(menuActions, sb);
            }
            //过程管理列表新增按钮,初始化只能保存
            else if (alterOrderView.SourceType == "1")
            {
                SetOneButtonEnabled(menuActions, sb, "Save");
            }
            #region 待办列表
            else if (alterOrderView.SourceType == "2")
            {
                //类型为待办
                if (alterOrderView.ProcessType == "1")
                {
                    foreach (UIFunctionView item in menuActions)
                    {
                        string disabled = "";
                        if (item.ActionCode == "Withdraw" || item.ActionCode == "Receipt" || item.ActionCode == "Reminders")
                        {
                            disabled = "disabled='false'";
                        }
                        else if (item.ActionCode == "Back")
                        {
                            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(alterOrderView.FlowCode, false, alterOrderView.AssociatedNodeCode);
                            if (flowNodeView.NodeType == 1)
                            {
                                disabled = "disabled='false'";
                            }
                        }
                        else if (item.ActionCode == "Cancel")
                        {
                            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(alterOrderView.FlowCode, false, alterOrderView.AssociatedNodeCode);
                            if (flowNodeView.NodeLevel > 1 || flowNodeView.NodeType == 1)
                            {
                                disabled = "disabled='false'";
                            }
                        }
                        sb.Append(ToolButton(item, disabled));
                    }
                }
                //类型为传阅
                else
                {
                    foreach (UIFunctionView item in menuActions)
                    {
                        string disabled = "disabled='false'";
                        if (item.ActionCode == "Circulated" || item.ActionCode == "Receipt")
                        {
                            disabled = "";
                        }
                        sb.Append(ToolButton(item, disabled));
                    }
                }
            }
            #endregion

            #region 已办列表
            else if (alterOrderView.SourceType == "3")
            {
                //流转已办
                if (alterOrderView.ProcessType == "1")
                {
                    foreach (UIFunctionView item in menuActions)
                    {
                        string disabled = "disabled='false'";
                        if (alterOrderView.HandleState != "2" && alterOrderView.HandleState != "3")
                        {
                            if (item.ActionCode == "Withdraw")
                            {
                                //获取撤回到的节点信息
                                FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(alterOrderView.FlowCode, false, alterOrderView.ProcessdOrCirculatedNodeCode);
                                List<FlowNodeView> lstCirculationNode = new List<FlowNodeView>();
                                Dictionary<string, List<FlowNodeView>> dicConditionAndCirculationNode = new Dictionary<string, List<FlowNodeView>>();
                                bool isCanWithdraw = CanWithdraw(flowNodeView, alterOrderView.AlterOrderID.ToString(), alterOrderView.FlowCode, alterOrderView.ProcessdOrCirculatedUserDepartment, lstCirculationNode, dicConditionAndCirculationNode);
                                if (isCanWithdraw)
                                {
                                    disabled = "";
                                }
                            }
                            else if (item.ActionCode == "Circulated" || item.ActionCode == "Reminders")
                            {
                                disabled = "";
                            }
                        }
                        sb.Append(ToolButton(item, disabled));
                    }
                }
                //回退已办、终止已办
                else if (alterOrderView.ProcessType == "2" || alterOrderView.ProcessType == "3" || alterOrderView.ProcessType == "6")
                {
                    SetAllDisabled(menuActions, sb);
                }
                //本人传阅或者已阅
                else
                {
                    SetOneButtonEnabled(menuActions, sb, "Circulated");
                }
            }
            #endregion

            //流程消息
            else if (alterOrderView.SourceType == "4")
            {
                SetAllDisabled(menuActions, sb);
            }

            ViewBag.ToolBarInfo = sb.ToString();
        }

        private void SetAllDisabled(List<UIFunctionView> menuActions, StringBuilder sb)
        {
            foreach (UIFunctionView item in menuActions)
            {
                sb.Append(ToolButton(item, "disabled='false'"));
            }
        }

        private void SetOneButtonEnabled(List<UIFunctionView> menuActions, StringBuilder sb, string code)
        {
            foreach (UIFunctionView item in menuActions)
            {
                string disabled = "disabled='false'";
                if (item.ActionCode == code)
                {
                    disabled = "";
                }
                sb.Append(ToolButton(item, disabled));
            }
        }

        public string ToolButton(UIFunctionView item, string disabled = "")
        {
            return "<a href='javascript:void(0)' id='btn" + item.ActionCode + "' class='easyui-linkbutton' onclick='" + item.MenuCode + "." + item.ActionCode + "()' data-options='plain:true,iconCls:\"" + item.Icon + "\"'" + disabled + ">" + item.ActionName + "</a>";
        }
        #endregion

        #region 判断是否有撤回权限
        /// <summary>
        /// 判断是否有撤回权限
        /// </summary>
        /// <param name="flowNodeView">撤回到的节点信息</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="lstCirculationNode">根据withdrawNodeCode获取要流转的节点列表</param>
        /// <param name="dicConditionAndCirculationNode">根据withdrawNodeCode获取条件节点流转的节点字典</param>
        /// <returns></returns>
        private bool CanWithdraw(FlowNodeView flowNodeView, string recordID, string flowCode, string processUserDepartment, List<FlowNodeView> lstCirculationNode, Dictionary<string, List<FlowNodeView>> dicConditionAndCirculationNode)
        {
            //分析撤回到的节点的XML里面的circulationCell，获取节点Code数组
            string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, recordID);

            //根据第一次获取到的节点数组，获取所有的中间经过的条件节点和流转节点
            foreach (string flowNodeCode in arrFlowNodeCode)
            {
                List<FlowNodeView> lstConditionAndCirculationNode = new List<FlowNodeView>();
                GetConditionAndCirculationNode(flowCode, flowNodeCode, recordID, processUserDepartment, lstCirculationNode, lstConditionAndCirculationNode);
                dicConditionAndCirculationNode.Add(flowNodeCode, lstConditionAndCirculationNode);
            }

            //判断是否流转的节点对应的每个人在待办里面都能找到
            List<BaklogTaskView> lstBaklogTask = BaklogTaskService.GetBaklogTaskByRecordID(recordID);
            foreach (FlowNodeView circulationNode in lstCirculationNode)
            {
                string[] processDepartmentAndPersonArr = circulationNode.DefaultProcessPerson.Split(',');
                foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                {
                    string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');

                    //是否找不到待办
                    BaklogTaskView existsBaklogTaskView = lstBaklogTask.SingleOrDefault(b => b.CurrentFlowNodeCode == circulationNode.NodeCode && b.CurrentProcessPerson == subProcessDepartmentAndPersonArr[1]);
                    if (existsBaklogTaskView == null)
                    {
                        return false;
                    }

                    //是否点击了保存按钮
                    AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderBackupByCondition(recordID, circulationNode.NodeCode, subProcessDepartmentAndPersonArr[0], subProcessDepartmentAndPersonArr[1]);
                    if (alterOrderView != null && alterOrderView.SaveState == "1")
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 根据节点的XML获取流转节点Code
        /// </summary>
        /// <param name="nodeXML">节点的XML</param>
        /// <param name="recordID">单据ID</param>
        /// <returns></returns>
        private string[] GetNodeCodeByXMLForCirculation(string nodeXML, string recordID)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(nodeXML);
            XmlNodeList nodeList = doc.SelectNodes("NodeXML/circulationCell");
            string getType = nodeList[0].SelectSingleNode("getType").InnerText;
            string processNodeCode = string.Empty;
            if (getType.ToLower() == "value")
            {
                processNodeCode = nodeList[0].SelectSingleNode("cellsName").InnerText;
            }
            else
            {
                string functionName = nodeList[0].SelectSingleNode("functionName").InnerText;
                Hashtable para = new Hashtable();
                para.Add("IsGetBusinessData", true);
                para.Add("RecordID", recordID);
                XmlNode paraNode = nodeList[0].SelectSingleNode("functionParam");
                if (paraNode != null)
                {
                    para.Add(paraNode.Name, paraNode.InnerText);
                }
                processNodeCode = FlowUtilsService.ExecuteCommand(functionName, para) as string;
            }
            return processNodeCode.Split(',');
        }

        /// <summary>
        /// 获取所有的中间经过的条件节点和流转节点
        /// </summary>
        /// <param name="flowCode">流程编码</param>
        /// <param name="flowNodeCode">流程节点编码</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="dicCirculationNode">记录流转节点的字典</param>
        /// <param name="lstConditionAndCirculationNode">记录条件节点和流转节点的List</param>
        private void GetConditionAndCirculationNode(string flowCode, string flowNodeCode, string recordID, string processUserDepartment, List<FlowNodeView> lstCirculationNode, List<FlowNodeView> lstConditionAndCirculationNode)
        {
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, flowNodeCode);
            lstConditionAndCirculationNode.Add(flowNodeView);
            if (flowNodeView.NodeType == 2)
            {
                //如果是条件节点，获取条件节点的XML数据并解析，递归调用
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, recordID);
                foreach (string nextNodeCode in arrFlowNodeCode)
                {
                    GetConditionAndCirculationNode(flowCode, nextNodeCode, recordID, processUserDepartment, lstCirculationNode, lstConditionAndCirculationNode);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(flowNodeView.NodeXML))
                {
                    flowNodeView.DefaultProcessPerson = GetDefaultProcessPerson(flowNodeView.NodeXML, processUserDepartment);
                }
                lstCirculationNode.Add(flowNodeView);
            }
        }

        /// <summary>
        /// 获取缺省处理人和部门
        /// </summary>
        /// <param name="docPerson">节点xml文档</param>
        /// <param name="recordID">单据ID</param>
        /// <returns></returns>
        private string GetDefaultProcessPerson(string nodeXML, string processUserDepartment)
        {
            string defaultProcessPerson = string.Empty;
            XmlDocument docPerson = new XmlDocument();
            docPerson.LoadXml(nodeXML);
            XmlNode personNode = docPerson.SelectSingleNode("NodeXML/defaultProcessPerson");
            if (personNode != null)
            {
                string processPersonGetType = personNode.SelectSingleNode("getType").InnerText;
                if (processPersonGetType == "value")
                {
                    defaultProcessPerson = personNode.SelectSingleNode("presonList").InnerText;
                }
                else
                {
                    string functionName = personNode.SelectSingleNode("functionName").InnerText;
                    Hashtable para = new Hashtable();
                    para.Add("OrgCode", processUserDepartment);
                    XmlNode paraNode = personNode.SelectSingleNode("functionParam");
                    if (paraNode != null)
                    {
                        para.Add(paraNode.Name, paraNode.InnerText);
                    }
                    defaultProcessPerson = FlowUtilsService.ExecuteCommand(functionName, para) as string;
                }
            }
            return defaultProcessPerson;
        }
        #endregion

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Save(AlterOrderView model)
        {
            try
            {
                if (model.SourceType == "1")
                {
                    AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderBackupByID(model.ID);
                    if (alterOrderView == null)
                    {
                        List<BaklogTaskView> addList = new List<BaklogTaskView>();
                        addList.Add(new BaklogTaskView()
                        {
                            ID = GuidHelper.NewGuid(),
                            RecordID = model.AlterOrderID.ToString(),
                            TaskType = model.FlowCode,
                            RequestDate = model.RequestDate,
                            CurrentFlowNodeCode = model.AssociatedNodeCode,
                            CurrentProcessPersonDepartment = model.LastUpdateUserDepartment,
                            CurrentProcessPerson = model.LastUpdateUser,
                            NodeLevel = 1
                        });
                        BaklogTaskService.AddBaklogTask(addList);
                    }
                }
                model.LastUpdateTime = DateTime.Now;
                model.SaveState = "1";
                model.SendState = "0";

                List<AlterOrderBillView> alterOrderBillList = new List<AlterOrderBillView>();
                if (model.AlterOrderBillListJson != "[]")
                {
                    string alterBillListJsonNew = "{\"lstAlterBillView\":" + model.AlterOrderBillListJson + "}";
                    XmlNode alterBillListNode = XMLJsonUtils.JsonToXml(alterBillListJsonNew).SelectSingleNode("root/lstAlterBillView");
                    foreach (XmlNode childNode in alterBillListNode.ChildNodes)
                    {
                        AlterOrderBillView add = new AlterOrderBillView();
                        XmlNode node = childNode.SelectSingleNode("ID");
                        if (node == null || string.IsNullOrEmpty(node.InnerText))
                        {
                            add.ID = GuidHelper.NewGuid();
                            add.AlterOrderBillID = GuidHelper.NewGuid();
                        }
                        else
                        {
                            add.ID = childNode.SelectSingleNode("ID").InnerText.ToGuid();
                            add.AlterOrderBillID = childNode.SelectSingleNode("AlterOrderBillID").InnerText.ToGuid();
                        }
                        add.PID = childNode.SelectSingleNode("PID").InnerText.ToGuid();
                        add.BillCode = childNode.SelectSingleNode("BillCode").InnerText;
                        add.BillName = childNode.SelectSingleNode("BillName").InnerText;
                        add.Unit = childNode.SelectSingleNode("Unit").InnerText;
                        add.OriginalCount = childNode.SelectSingleNode("OriginalCount").InnerText == string.Empty ? 0 : Convert.ToDecimal(childNode.SelectSingleNode("OriginalCount").InnerText);
                        add.AfterAlterCount = childNode.SelectSingleNode("AfterAlterCount").InnerText == string.Empty ? 0 : Convert.ToDecimal(childNode.SelectSingleNode("AfterAlterCount").InnerText);
                        add.AlterCount = childNode.SelectSingleNode("AlterCount").InnerText == string.Empty ? 0 : Convert.ToDecimal(childNode.SelectSingleNode("AlterCount").InnerText);
                        add.Price = childNode.SelectSingleNode("Price").InnerText == string.Empty ? 0 : Convert.ToDouble(childNode.SelectSingleNode("Price").InnerText);
                        add.AlterMoney = childNode.SelectSingleNode("AlterMoney").InnerText == string.Empty ? 0 : Convert.ToDouble(childNode.SelectSingleNode("AlterMoney").InnerText);
                        add.Remark = childNode.SelectSingleNode("Remark") == null ? string.Empty : childNode.SelectSingleNode("Remark").InnerText;
                        add.AssociatedNodeCode = model.AssociatedNodeCode;
                        add.LastUpdateUserDepartment = model.LastUpdateUserDepartment;
                        add.LastUpdateUser = model.LastUpdateUser;
                        add.LastUpdateTime = DateTime.Now;
                        add.SendState = "0";
                        alterOrderBillList.Add(add);
                    }
                }
                AlterOrderService.SaveAlterOrderBackup(model, alterOrderBillList);

                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        #region 判断是否能发送
        public ActionResult CanCirculation(string flowCode, string recordID, string currentFlowNodeCode, string processUserDepartment)
        {
            try
            {
                //分析当前节点的XML里面的circulationCell，获取节点Code数组
                FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, currentFlowNodeCode);
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, recordID);

                string message = string.Empty;
                bool isEnd = arrFlowNodeCode.Length == 1 && arrFlowNodeCode[0].ToLower() == "end";
                if (!isEnd)
                {
                    //根据第一次获取到的节点数组，获取所有的流转节点
                    List<FlowNodeView> lstCirculationNode = new List<FlowNodeView>();
                    foreach (string flowNodeCode in arrFlowNodeCode)
                    {
                        GetCirculationNode(flowCode, flowNodeCode, recordID, processUserDepartment, lstCirculationNode);
                    }

                    if (lstCirculationNode.Count > 0)
                    {
                        foreach (FlowNodeView circulationNode in lstCirculationNode)
                        {
                            if (string.IsNullOrEmpty(circulationNode.DefaultProcessPerson))
                            {
                                message += "【" + circulationNode.NodeName + "】,";
                            }
                        }
                        if (!string.IsNullOrEmpty(message))
                        {
                            message = "节点" + message.Trim(',') + "没有设置处理人！";
                        }
                    }
                    else
                    {
                        message = "没有发送节点！";
                    }
                }
                return Content(message);
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        private void GetCirculationNode(string flowCode, string flowNodeCode, string recordID, string processUserDepartment, List<FlowNodeView> lstCirculationNode)
        {
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, flowNodeCode);
            if (flowNodeView.NodeType == 2)
            {
                //如果是条件节点，获取条件节点的XML数据并解析，递归调用
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, recordID);
                foreach (string nextNodeCode in arrFlowNodeCode)
                {
                    GetCirculationNode(flowCode, nextNodeCode, recordID, processUserDepartment, lstCirculationNode);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(flowNodeView.NodeXML))
                {
                    flowNodeView.DefaultProcessPerson = GetDefaultProcessPerson(flowNodeView.NodeXML, processUserDepartment);
                }
                lstCirculationNode.Add(flowNodeView);
            }
        }
        #endregion

        public ActionResult Withdraw(AlterOrderView model, string withdrawNodeCode)
        {
            try
            {
                //获取撤回到的节点信息
                FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, withdrawNodeCode);
                List<FlowNodeView> lstCirculationNode = new List<FlowNodeView>();
                Dictionary<string, List<FlowNodeView>> dicConditionAndCirculationNode = new Dictionary<string, List<FlowNodeView>>();
                bool isCanWithdraw = CanWithdraw(flowNodeView, model.AlterOrderID.ToString(), model.FlowCode, model.ProcessdOrCirculatedUserDepartment, lstCirculationNode, dicConditionAndCirculationNode);
                if (isCanWithdraw)
                {
                    FlowUtilsService.Withdraw(flowNodeView, model.FlowCode, model.AlterOrderID.ToString(), model.ProcessdOrCirculatedUserDepartment, model.RequestDate, lstCirculationNode, dicConditionAndCirculationNode);
                    return Content("Success");
                }
                else
                {
                    return Content("已经有人处理，不能撤回！");
                }
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        public ActionResult Cancel(string flowCode, string id)
        {
            try
            {
                FlowUtilsService.Cancel(flowCode, User.Identity.Name, id);
                AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderByID(id);
                alterOrderView.HandleState = "3";
                AlterOrderService.SaveAlterOrder(alterOrderView, new List<AlterOrderBillView>());
                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        public ActionResult Reminders(string flowCode, string id)
        {
            try
            {
                FlowUtilsService.Reminders(id, flowCode, User.Identity.Name);
                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        public ActionResult GenerateGraph(string flowCode, string id)
        {
            AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderByID(id);
            string handleState = "";
            if (alterOrderView != null)
            {
                handleState = alterOrderView.HandleState;
            }
            WorkFlowView workFlowView = FlowUtilsService.GenerateGraph(flowCode, id, handleState);
            return Json(workFlowView, JsonRequestBehavior.AllowGet);
        }

        #region 变更令主界面显示相关
        public ActionResult AlterOrderList()
        {
            //ViewBag.ToolBarInfo = base.GetToolBarInfo();
            ConstructToolsForList();
            return View();
        }

        private void ConstructToolsForList()
        {
            StringBuilder sb = new StringBuilder();
            var orgs = (from u in UserInfoService.Users
                        join uo in UserOrgService.UserOrgs on u.ID equals uo.UserID
                        join o in OrgInfoService.Orgs on uo.OrgID equals o.ID
                        where u.UserName == User.Identity.Name
                        select o).ToList();
            if (orgs.Count() > 0)
            {
                string requestDepartmentListForAlterOrderOne = ConfigurationManager.AppSettings["RequestDepartmentListForAlterOrderOne"] as string;
                foreach (var orgInfo in orgs)
                {
                    if (CommonUtils.FlowFilterAndRequestUtils.IsHasOrgCodeAndUserNameInStr(requestDepartmentListForAlterOrderOne, orgInfo.OrgCode, User.Identity.Name))
                    {
                        List<UIFunctionView> menuActions = base.GetUserMenuActions();
                        foreach (UIFunctionView item in menuActions)
                        {
                            string btn = "<a href='javascript:void(0)' id='btn" + item.ActionCode + "' class='easyui-linkbutton' onclick='" + item.MenuCode + "." + item.ActionCode + "()' data-options='plain:true,iconCls:\"" + item.Icon + "\"'>" + item.ActionName + "</a>";
                            sb.Append(btn);
                        }
                        break;
                    }
                }
            }
            ViewBag.ToolBarInfo = sb.ToString();
        }

        public ActionResult GetAlterOrderList(string projectID, string contractID)
        {
            List<AlterOrderView> lstAlterOrderView = new List<AlterOrderView>();
            if (!string.IsNullOrEmpty(projectID) && !string.IsNullOrEmpty(contractID))
            {
                lstAlterOrderView=AlterOrderService.GetAlterOrderList(projectID.ToGuid(), contractID.ToGuid());
                //GetAlterOrderListForPreview(ref lstAlterOrderView);
            }
            return Json(lstAlterOrderView, JsonRequestBehavior.AllowGet);
        }

        private void GetAlterOrderListForPreview(ref List<AlterOrderView> lstAlterOrderView)
        {
            //获取需要做合同筛选的顶级部门，如果不为空并且不是超级管理员，则需要对登陆用户的变更令列表进行筛选：只能查看登陆用户所属部门或者子部门与客户端合同对应单位相同的那些
            string topDepartmentOfNeedFilterContractStr = ConfigurationManager.AppSettings["TopDepartmentOfNeedFilterContract"] as string;
            if (!string.IsNullOrEmpty(topDepartmentOfNeedFilterContractStr) && SystemData.Instance.CurrentUser.UserType == UserType.Common)
            {
                //获取登陆用户的机构信息
                List<OrgInfo> orgs = (from u in UserInfoService.Users
                                      join uo in UserOrgService.UserOrgs on u.ID equals uo.UserID
                                      join o in OrgInfoService.Orgs on uo.OrgID equals o.ID
                                      where u.UserName == User.Identity.Name
                                      select o).ToList();
                if (orgs.Count() > 0)
                {
                    //获取能新增施工合同的所有部门
                    List<Guid> lstAllAddConstructionContractDepartment = new List<Guid>();
                    string[] addConstructionContractTopDepartmentArr = topDepartmentOfNeedFilterContractStr.Split(',');
                    foreach (string addConstructionContractTopDepartment in addConstructionContractTopDepartmentArr)
                    {
                        OrgInfo orgInfo = OrgInfoService.Orgs.SingleOrDefault(o => o.OrgCode == addConstructionContractTopDepartment);
                        if (orgInfo != null)
                        {
                            lstAllAddConstructionContractDepartment.Add(orgInfo.ID);
                            FlowFilterAndRequestUtils.GetSubOrgInfo(orgInfo.ID, ref lstAllAddConstructionContractDepartment);
                        }
                    }

                    //如果所有能新增施工合同的机构包含登陆用户所在部门，则需要筛选数据
                    if (FlowFilterAndRequestUtils.IsContainLoginOrg(lstAllAddConstructionContractDepartment, orgs))
                    {
                        string correspondenceUnitStr = string.Empty;
                        foreach (var org in orgs)
                        {
                            correspondenceUnitStr += "'" + org.ID + "',";
                            FlowFilterAndRequestUtils.GetSubCorrespondenceUnit(org.ID, ref correspondenceUnitStr);
                        }
                        string sql = "select * from V_ContractInfoes where CorrespondenceUnit in (" + correspondenceUnitStr.Trim(',') + ")";
                        var lstContractInfo = DbSqlHelper<VMContractInfo>.SqlQueryCommon(sql);

                        lstAlterOrderView = (from a in lstAlterOrderView
                                             join c in lstContractInfo
                                             on a.ContractID equals c.ID
                                             select a).ToList();
                    }
                }
            }
        }

        ////获取指定部门的下级部门
        //private void GetSubOrgInfo(Guid parentID, ref List<Guid> lstAllAddConstructionContractDepartment)
        //{
        //    IQueryable<OrgInfo> lstOrgInfo = OrgInfoService.Orgs.Where(o => o.PID == parentID);
        //    foreach (OrgInfo orgInfo in lstOrgInfo)
        //    {
        //        lstAllAddConstructionContractDepartment.Add(orgInfo.ID);
        //        GetSubOrgInfo(orgInfo.ID, ref lstAllAddConstructionContractDepartment);
        //    }
        //}

        ////所有能新增施工合同的机构是否包含登陆用户所在部门
        //private bool IsContainLoginOrg(List<Guid> lstAllAddConstructionContractDepartment, List<OrgInfo> orgs)
        //{
        //    foreach (OrgInfo org in orgs)
        //    {
        //        if (lstAllAddConstructionContractDepartment.Contains(org.ID))
        //        {
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        //private void GetSubCorrespondenceUnit(Guid parentID, ref string correspondenceUnitStr)
        //{
        //    IQueryable<OrgInfo> lstOrgInfo = OrgInfoService.Orgs.Where(o => o.PID == parentID);
        //    foreach (OrgInfo orgInfo in lstOrgInfo)
        //    {
        //        correspondenceUnitStr += "'" + orgInfo.ID.ToString() + "',";
        //        GetSubCorrespondenceUnit(orgInfo.ID, ref correspondenceUnitStr);
        //    }
        //}
        #endregion

        public ActionResult DeleteSelectAlterOrder()
        {
            string alterOrderID = Request["AlterOrderID"];
            var result = AlterOrderService.DeleteSelectAlterOrder(alterOrderID);
            if (result.ResultType == OperationResultType.Success)
                return Content(OperationResultType.Success.ToString());
            return Content(result.Message);
        }


        public ActionResult AddAterOrderBill(string contractID)
        {
            ProjectContractView projectContractView = new ProjectContractView();
            projectContractView.ContractID = contractID;
            return View(projectContractView);
        }
    }
}